package com.isoftstone.disk.service.impl;

import com.isoftstone.disk.entity.FileInfoTreeEntity;
import com.isoftstone.disk.entity.FileObsEntity;
import com.isoftstone.disk.entity.RenameFile;
import com.isoftstone.disk.repository.FileDao;
import com.isoftstone.disk.service.DiskService;
import com.isoftstone.platform.common.uitl.DateUtil;
import com.isoftstone.platform.common.uitl.FileUtil;
import com.isoftstone.platform.entity.PadingRstType;
import com.isoftstone.platform.model.entity.FileEntity;
import com.obs.services.ObsClient;
import com.obs.services.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.io.*;
import java.util.Date;
import java.util.List;

import static com.isoftstone.platform.common.uitl.DataUtil.sysTime;

@Service("diskService")
public class DiskServiceImpl implements DiskService {
    @Value("${ak}")
    private String ak="";
    @Value("${sk}")
    private String sk="";
    @Value("${end.point}")
    private String endPoint="";
    @Value("${backet.name}")
    private String backetName="";

    @Resource
    private FileDao fileDao;

    private static ObsClient obsClient = null;
    private synchronized ObsClient getSigleInstance(){
        if(obsClient == null){
            obsClient = new ObsClient(ak,sk,endPoint);
        }
        return obsClient;
    }

    @Override
    public void addFile(String fileNameDesc, String name, InputStream inputStream) {
            ObsClient obsClient = getSigleInstance();
            obsClient.putObject(backetName,name,inputStream);
    }

    @Override
    public ResponseEntity<byte[]> download(String fileId) {

        ObsClient obsClient = getSigleInstance();
        ObsObject obsObject = obsClient.getObject(backetName, fileId);
        try(ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();){
            InputStream inputStream = obsObject.getObjectContent();
            byte[] block = new byte[1024];
            int lengh = 0;
            while((lengh = inputStream.read(block))> 0){
                byteOutputStream.write(block,0,lengh);
                byteOutputStream.flush();
            }
            HttpHeaders headers =
                    new HttpHeaders();
            headers.setContentDispositionFormData("attachment",fileId);//告知浏览器以下载方式打开
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置MIME类型
            return new ResponseEntity<byte[]>(
                    byteOutputStream.toByteArray(),
                    headers,
                    HttpStatus.CREATED);
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    //保存文件信息到数据库
    @Override
    public void saveFileInfToDatabase(String fileNameDesc, String name) {
        //通过OBS查询当前文件的信息
        ObsClient obsClient =  getSigleInstance();
        ObjectMetadata metadata = obsClient.getObjectMetadata(backetName, name);

        FileObsEntity fileObsEntity;
        fileObsEntity= new FileObsEntity();
        fileObsEntity.setObjectKey(name);
        fileObsEntity.setLastModified(DateUtil.formatDate(metadata.getLastModified()));
        fileObsEntity.setContentLength(FileUtil.clcltn(metadata.getContentLength()/1024f));
        //调用FileDao中的函数进行数据库操作

        FileEntity fileInfo= new FileEntity();
        fileInfo.setParentId(-1);//默认上传到最上层目录 -1
        fileInfo.setFileType(1);
        fileInfo.setFileName(fileObsEntity.getObjectKey());
        fileInfo.setFileLength(Double.parseDouble(fileObsEntity.getContentLength()));
        fileInfo.setFileLastTime(fileObsEntity.getLastModified());
        fileInfo.setFileParentDirectory("0");
        fileInfo.setFileOwner("0");
        fileInfo.setIsMyShare("0");
        fileInfo.setIsDelete("0");
        fileInfo.setIsCollect("0");
        fileDao.saveFileInfo(fileInfo);
    }

    //回收文件到回收站
    @Override
    public void recycle(int fileId) {
        //获取文件id
        //进行数据库操作，修改文件属性 is_delete
        fileDao.recycleFile(fileId);
    }

    //获取文件信息
    @Override
    public PadingRstType<FileEntity> getFileInfolist() {
        PadingRstType<FileEntity> prt = new PadingRstType<FileEntity>();
        FileEntity fileInfoEntity;
        //查询文件列表
        List<FileEntity> lists =fileDao.queryFileInfoList(-1);
        prt.setTotal(lists.size());
        prt.setRawRecords(lists);
        prt.putItems();
        return prt;
    }

    //获取已经删除的文件信息
    @Override
    public PadingRstType<FileEntity> getDeleteFileslist() {
        PadingRstType<FileEntity> prt = new PadingRstType<FileEntity>();
        FileEntity fileInfoEntity;
        //查询文件列表
        List<FileEntity> lists =fileDao.getDeleteFileslist();
        prt.setTotal(lists.size());
        prt.setRawRecords(lists);
        prt.putItems();
        return prt;
    }

    //还原，从回收站还原
    @Override
    public void restore(int fileId) {
        //获取文件id
        //进行数据库操作，修改文件属性 is_delete
        fileDao.restoreFile(fileId);
    }

    //删除文件
    @Override
    public void delete(String fileId) {
        //获取文件id
        //删除
        ObsClient obsClient = getSigleInstance();
        obsClient.deleteObject(backetName,fileId);
        fileDao.delete(fileId);
    }

    //分享文件
    @Override
    public String share(String fileId) {
        // 创建ObsClient实例
        ObsClient obsClient = getSigleInstance();
        ObsObject obsObject = obsClient.getObject(backetName, fileId);
        // URL有效期，3600秒
        long expireSeconds = 3600L;
        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
        request.setBucketName(backetName);
        request.setObjectKey(obsObject.getObjectKey());
        request.setRequestDate(new Date());
        TemporarySignatureResponse signature = obsClient.createTemporarySignature(request);
        //获取支持图片转码的下载链接
        System.out.println("Getting object using temporary signature url:");
        System.out.println("\t" + signature.getSignedUrl());
        return signature.getSignedUrl();
    }

    //获取分享文件列表
    @Override
    public PadingRstType<FileEntity> getSharedFileslist() {
        PadingRstType<FileEntity> prt = new PadingRstType<FileEntity>();
        FileEntity fileInfoEntity;
        //查询文件列表
        List<FileEntity> lists =fileDao.getSharedFileInfoList();
        prt.setTotal(lists.size());
        prt.setRawRecords(lists);
        prt.putItems();
        return prt;
    }

    //取消分享
    @Override
    public void cancelSharing(int fileId) {
        //获取文件id
        //取消分享
        fileDao.cancelSharingFile(fileId);
    }

    //进行分享
    @Override
    public void sharing(int fileId) {
        //获取文件id
        //分享
        fileDao.sharingFile(fileId);
    }

    //预览
    @Override
    public String preview(String fileId) {
        ObsClient obsClient =  getSigleInstance();

        System.out.println("执行预览操作~Now Preview Service:(preview)");
        String resultUrl;
        String objectKey = fileId;
        TemporarySignatureRequest request = new TemporarySignatureRequest();
        request.setBucketName(backetName);
        request.setObjectKey(objectKey);
        request.setRequestDate(new Date());
        // 1分钟后链接失效
        request.setExpires(40*60);
        TemporarySignatureResponse signature = obsClient.createTemporarySignature(request);
        resultUrl = signature.getSignedUrl();
        System.out.println("获取临时URL~Get Temp Url:(preview):url="+resultUrl);
        return resultUrl;
    }

    //获取目录树
    @Override
    public List<FileInfoTreeEntity> queryFileInfoZtreeList(@RequestParam("roleuuid")String roleuuid) {
        List<FileInfoTreeEntity> list = fileDao.queryFileInfoZtreeList();
        return list;
    }

    //新建文件夹
    @Override
    public void newFolders(String mid,String folderName) {
            FileEntity fileInfo;
            int i = Integer.valueOf(mid);
            fileInfo = new FileEntity();
            String file_name=folderName; //名称
            String file_last_time=sysTime(); //修改时间
            String file_parent_directory="0";//父目录
            String file_owner="0"; //拥有者
            String is_my_share="0";//是否分析
            String is_delete="0"; //是否删除
            String is_collect="0";//是否收藏

            fileInfo.setParentId(i);//默认上传到最上层目录 -1
            fileInfo.setFileType(0);
            fileInfo.setFileName(file_name);
            fileInfo.setFileLength(0.0);
            fileInfo.setFileLastTime(file_last_time);
            fileInfo.setFileParentDirectory(file_parent_directory);
            fileInfo.setFileOwner(file_owner);
            fileInfo.setIsMyShare(is_my_share);
            fileInfo.setIsDelete(is_delete);
            fileInfo.setIsCollect(is_collect);
            fileDao.saveFileInfo(fileInfo);
    }

    //新建文件  -- 测试 未完成
    @Override
    public void newFiles(String mid, String fileName) {
        FileEntity fileInfo;
        //通过OBS查询当前文件的信息
        ObsClient obsClient =  getSigleInstance();
        ObjectMetadata metadata = obsClient.getObjectMetadata(backetName, fileName);

            int i = Integer.valueOf(mid);
            fileInfo = new FileEntity();
            FileObsEntity fileObsEntity;
            fileObsEntity= new FileObsEntity();
            fileObsEntity.setObjectKey(fileName);
            fileObsEntity.setLastModified(DateUtil.formatDate(metadata.getLastModified()));
            fileObsEntity.setContentLength(FileUtil.clcltn(metadata.getContentLength()/1024f));
            //调用FileDao中的函数进行数据库操作
            String file_name=fileObsEntity.getObjectKey(); //名称
            String file_length=fileObsEntity.getContentLength();//长度
            String file_last_time=fileObsEntity.getLastModified(); //修改时间
            String file_parent_directory="0";//父目录
            String file_owner="0"; //拥有者
            String is_my_share="0";//是否分析
            String is_delete="0"; //是否删除
            String is_collect="0";//是否收藏

            fileInfo.setParentId(i);//默认上传到最上层目录 -1
            fileInfo.setFileType(1);
            fileInfo.setFileName(file_name);
            fileInfo.setFileLength(Double.parseDouble(file_length));
            fileInfo.setFileLastTime(file_last_time);
            fileInfo.setFileParentDirectory(file_parent_directory);
            fileInfo.setFileOwner(file_owner);
            fileInfo.setIsMyShare(is_my_share);
            fileInfo.setIsDelete(is_delete);
            fileInfo.setIsCollect(is_collect);
            fileDao.saveFileInfo(fileInfo);

    }

    //查询 文件列表
    @Override
    public PadingRstType<FileEntity> queryFileOfParent(Integer valueOf) {
        PadingRstType<FileEntity> prt = new PadingRstType<FileEntity>();
        FileEntity fileInfoEntity;
        //查询文件列表
        List<FileEntity> lists =fileDao.queryFileInfoList(valueOf);
        prt.setTotal(lists.size());
        prt.setRawRecords(lists);
        prt.putItems();
        return prt;
    }

    //查询 PID
    @Override
    public int backToPardir(Integer valueOf) {
        int pid=fileDao.getPardirId(valueOf);
        System.out.println("pid="+pid);
        return pid;
    }

    @Override
    public void moveFile(String id, String[] ps) {
        for (String s : ps) {
            int i = Integer.valueOf(s);
            fileDao.moveFile(Integer.valueOf(id),i);
        }
    }

    //重命名
    @Override
    public void updateName(RenameFile renamefile) {
        ObsClient obsClient = getSigleInstance();
        ObsObject obsObject = obsClient.getObject(backetName, renamefile.getOldFileName());
        obsClient.putObject(backetName, renamefile.getNewFileName(), obsObject.getObjectContent());
        obsClient.deleteObject(backetName, renamefile.getOldFileName());
        fileDao.renameFileName(renamefile);
    }

    @Override
    public void copyFile(String id, String[] ps) {
        for (String s : ps) {
            int i = Integer.valueOf(s);
            FileEntity fileEntity = fileDao.queryFileInfo(id);
            fileEntity.setId(null);
            fileEntity.setParentId(i);
            fileDao.copyFile(fileEntity);
        }
    }
}
